import { Injectable } from '@nestjs/common';
import * as ALY from 'aliyun-sdk';
// tslint:disable-next-line:max-line-length
import { transformQueryToStr, addSelectList, addSelectCount, getEventNumAndUserNumQueryStr, getTimeQueryStr, getCategoryNumByLogStr } from './sls.util';
import NP from 'number-precision';

const sls = new ALY.SLS({
  accessKeyId: 'LTAI2HEgJhoUQxyf', // 步骤2获取的密钥
  secretAccessKey: 'TKzszN6cfyc99y5lgn0Th3hzsddbSW', // 步骤2获取的密钥值
  endpoint: 'http://cn-hangzhou.sls.aliyuncs.com',
  apiVersion: '2015-06-01'
});

@Injectable()
export class SlsService {
  defaultOpt: {
    projectName: string;
    logStoreName: string;
  }
  constructor() {
    this.defaultOpt = {
      projectName: 'trycatch',
      logStoreName: 'log',
    }
  }
  private getData(opt) {
    return new Promise((resolve, reject) => {
      sls.getLogs(opt, function (error, data) {
        if (error) {
          reject(error);
        } else {
          resolve(Object.values(data.body));
        }
      });
    });
  }
  public query = async function (opt) {
    const { query: query1, ...other } = opt;
    const queryStr = transformQueryToStr(query1);
    const defaultOpt = {
      ...this.defaultOpt,
      from: other.from,
      to: other.to,
    }
    const listOpt = {
      ...defaultOpt,
      query: addSelectList(queryStr, other.line, other.offset)
    }
    const countOpt = {
      ...defaultOpt,
      query: addSelectCount(queryStr)
    }

    return Promise.all([this.getData(listOpt), this.getData(countOpt)]).then(([list, countList]) => {

      return {
        // tslint:disable-next-line:max-line-length
        list: list.map(({ __date__, __line__, __log_count__, __log_pattern__, __pack_meta__, __sls_query_parameter__, __source__, __tag__, __time__, __topic__, __log_signature__, time, stack, behavior, ...item }: any) => ({
          ...item,
          time: Number(time) * 1000,
          stack: stack && JSON.parse(stack),
          behavior: behavior && JSON.parse(behavior)
        })),
        totalCount: Number(countList[0].totalCount)
      }
    })

  };

  public create(data: any[]) {
    return sls.putLogs({
      ...this.defaultOpt,
      logGroup: {
        logs: data
      }
    }, (error) => {
      console.log(error)
    })
  }

  public getEventNumAndUserNum(data) {
    const opt = {
      ...this.defaultOpt,
      from: 0,
      to: Math.floor(Date.now() / 1000),
      query: getEventNumAndUserNumQueryStr(data)
    }
    return this.getData({ ...opt }).then(res => {

      return {
        eventNum: res[0].eventNum,
        userNum: res[0].userNum
      }
    })

  }

  public queryNumByTime(data) {
    const { from, to, flag, ...query } = data;
    const opt = {
      ...this.defaultOpt,
      from, to,
      query: getTimeQueryStr(query, flag)
    }
    return this.getData({ ...opt }).then((res: any) => {
      // tslint:disable-next-line:max-line-length
      return res.reduce(({ totalCount, data }, item: any) => {
        return {
          data: data.concat({ time: item.time, eventNum: Number(item.eventNum), userNum: Number(item.userNum) }),
          totalCount: totalCount + Number(item.eventNum)
        }
      }, { data: [], totalCount: 0 });
    })
  }

  public queryCategory(data) {
    const { from, to, flag, ...query } = data;
    const opt = {
      ...this.defaultOpt,
      from, to,
      query: getCategoryNumByLogStr(query, flag)
    }

    return this.getData({ ...opt }).then((res: any) => {
      return res.reduce(({ data, totalCount }: any, item: any) => {
        return {
          data: data.concat({ name: item[flag], count: Number(item.count), percentage: NP.round(Number(item.percentage) * 100, 2) }),
          totalCount: totalCount + Number(item.count)
        }
      }, { data: [], totalCount: 0 });
    })
  }


}
